package server.handler;

import com.alibaba.fastjson.JSON;
import common.body.TcpBody;
import common.dto.ChannelStatDTO;
import common.enums.MsgTypeEnum;
import common.enums.ProtocolEnum;
import common.packet.BsPacket;
import common.packet.TcpPacket;
import lombok.extern.slf4j.Slf4j;
import org.tio.core.ChannelContext;
import org.tio.core.Tio;
import org.tio.core.TioConfig;
import org.tio.core.exception.TioDecodeException;
import org.tio.core.intf.Packet;
import org.tio.core.stat.ChannelStat;
import org.tio.server.intf.ServerAioHandler;
import server.container.ProxyServer;

import java.nio.ByteBuffer;

import static common.pojo.Constant.channelStatQueue;
import static common.pojo.Constant.defaultQueueSize;

/**
 * @author gitama
 * @version 1.0
 * @date 2021/5/10 4:13 下午
 * tcp 转发处理
 */
@Slf4j
public class TcpForwardServerHandler implements ServerAioHandler {

    @Override
    public Packet decode(ByteBuffer buffer, int limit, int position, int readableLength, ChannelContext channelContext) throws TioDecodeException {
        TcpPacket tcpPacket = new TcpPacket();
        byte[] dst = new byte[readableLength];
        buffer.get(dst);
        tcpPacket.setBody(dst);
        return tcpPacket;
    }

    @Override
    public ByteBuffer encode(Packet packet, TioConfig tioConfig, ChannelContext channelContext) {
        TcpPacket tcpPacket = (TcpPacket) packet;
        return ByteBuffer.wrap(tcpPacket.getBody());
    }

    @Override
    public void handler(Packet packet, ChannelContext channelContext) throws Exception {
        TcpPacket tcpPacket = (TcpPacket) packet;
        String token = (String) channelContext.get("token");
        if (channelStatQueue.size() < defaultQueueSize) {
            ChannelStatDTO channelStatDTO = new ChannelStatDTO(token, channelContext.getServerNode(), channelContext.stat);
            try {
                channelStatQueue.add(channelStatDTO);
            } catch (Exception e) {
                log.error(e.getMessage());
            }
        }
        TcpBody tcpBody = new TcpBody(tcpPacket.getBody(), channelContext.getId(), ProtocolEnum.TCP.getCode());
        BsPacket bsPacket = new BsPacket(MsgTypeEnum.TCP_FORWARD_REQ.getCode(), JSON.toJSONBytes(tcpBody));
        Tio.sendToBsId(ProxyServer.serverTioConfig, token, bsPacket);
    }

}
